use std::cell::RefCell;
use std::rc::Rc;

// Mediator trait，定义了通知方法
trait Mediator {
    fn notify(&self, sender: &str, event: &str);
}

// 具体中介者 ConcreteMediator
struct ConcreteMediator<'a> {
    component1: Rc<RefCell<Component1<'a>>>,
    component2: Rc<RefCell<Component2<'a>>>,
}

impl<'a> ConcreteMediator<'a> {
    // 创建具体中介者并初始化组件
    fn new(
        component1: Rc<RefCell<Component1<'a>>>,
        component2: Rc<RefCell<Component2<'a>>>,
    ) -> Self {
        Self {
            component1,
            component2,
        }
    }
}

// 实现 Mediator trait 对于 ConcreteMediator 的方法
impl<'a> Mediator for ConcreteMediator<'a> {
    fn notify(&self, _sender: &str, event: &str) {
        if event == "A" {
            println!("Mediator reacts on A and triggers following operations:");
            self.component2.borrow().do_c();
        } else if event == "D" {
            println!("Mediator reacts on D and triggers following operations:");
            self.component1.borrow().do_b();
        }
    }
}

// 组件 Component1
struct Component1<'a> {
    mediator: Option<Rc<RefCell<dyn Mediator + 'a>>>,
}

impl<'a> Component1<'a> {
    fn new() -> Self {
        Self { mediator: None }
    }

    // 设置中介者
    fn set_mediator(&mut self, mediator: Rc<RefCell<dyn Mediator + 'a>>) {
        self.mediator = Some(mediator);
    }

    // 组件的具体行为
    fn do_a(&self) {
        println!("Component 1 does A.");
        if let Some(mediator) = &self.mediator {
            mediator.borrow().notify("Component1", "A");
        }
    }

    fn do_b(&self) {
        println!("Component 1 does B.");
        if let Some(mediator) = &self.mediator {
            mediator.borrow().notify("Component1", "B");
        }
    }
}

// 组件 Component2
struct Component2<'a> {
    mediator: Option<Rc<RefCell<dyn Mediator + 'a>>>,
}

impl<'a> Component2<'a> {
    fn new() -> Self {
        Self { mediator: None }
    }

    // 设置中介者
    fn set_mediator(&mut self, mediator: Rc<RefCell<dyn Mediator + 'a>>) {
        self.mediator = Some(mediator);
    }

    // 组件的具体行为
    fn do_c(&self) {
        println!("Component 2 does C.");
        if let Some(mediator) = &self.mediator {
            mediator.borrow().notify("Component2", "C");
        }
    }

    fn do_d(&self) {
        println!("Component 2 does D.");
        if let Some(mediator) = &self.mediator {
            mediator.borrow().notify("Component2", "D");
        }
    }
}

// 主函数入口
pub fn main() {
    let component1 = Rc::new(RefCell::new(Component1::new())); // 创建 Component1 实例
    let component2 = Rc::new(RefCell::new(Component2::new())); // 创建 Component2 实例

    // 创建具体中介者并将组件传递给它
    let mediator = Rc::new(RefCell::new(ConcreteMediator::new(
        component1.clone(),
        component2.clone(),
    )));

    // 设置中介者
    component1.borrow_mut().set_mediator(mediator.clone());
    component2.borrow_mut().set_mediator(mediator.clone());

    // 触发组件行为
    component1.borrow().do_a(); // Component1 触发事件 A
    component2.borrow().do_d(); // Component2 触发事件 D
}
